// @flow
import React from 'react'
import styles from './CharterPage.css'
import NoticeMessage from '../NoticeMessage'
import { Button, Form, Input, Select, Icon } from 'antd'
import R from 'ramda'
const FormItem = Form.Item
const Option = Select.Option
type Props = {
  nextStep: Function,
  preStep: Function,
  kmxName: string,
  form: Object,
  // step: number
}
type State = {
  body: Object,
  allNodes: Array<Object>,
  activeNode: Array<Object>,
  loading: boolean
}
class CharterPage extends React.Component {
  props: Props
  state: State
  stepClick: Function
  getConfigEvn: () => void
  handleSubmit: () => void
  setDiskNodes: Function
  selectChange: Function
  checkConfirm: Function
  createKmx: Function
  constructor () {
    super()
    this.state = {
      body: {},
      allNodes: [],
      activeNode: [],
      loading: false
    }
    this.stepClick = this.stepClick.bind(this)
    this.createKmx = this.createKmx.bind(this)
    this.getConfigEvn = this.getConfigEvn.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
    this.setDiskNodes = this.setDiskNodes.bind(this)
    this.selectChange = this.selectChange.bind(this)
    this.checkConfirm = this.checkConfirm.bind(this)
  }

  componentWillReceiveProps (nextProps: Object) {
    console.info('CharterPage: ', nextProps)
    if (!R.equals(nextProps.kmxName, this.props.kmxName)) {
      this.getConfigEvn(nextProps.kmxName)
      this.getAllKmxNodes(nextProps.kmxName)
    }
  }

  stepClick (str: string) {
    if (str === 'pre') {
      this.props.preStep(3)
    }
    if (str === 'next') {
      this.handleSubmit()
    }
  }

  handleSubmit () {
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        console.log('Received values of form: ', values)
        let submitData = { mappings: [], kafka: {} }
        for (const key in values) {
          if (key.indexOf('disks') < 0 && key.indexOf('replicationFactor') < 0) {
            submitData.mappings.push({
              serviceName: key,
              hosts: [].concat(values[key])
            })
          } else {
            submitData.kafka['disks'] = [].concat(values['kafka-disks'])
            submitData.kafka['replicationFactor'] = values['kafka-replicationFactor']
          }
        }
        console.info('submitData: ', JSON.stringify(submitData, null, 4))
        this.createKmx(submitData)
      }
    })
  }

  // 配置KMX
  createKmx (data) {
    this.setState({ loading: true })
    const url = `${__CM_URL__}kmxes/${this.props.kmxName}`
    fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    })
    .then((response) => {
      if (!(response.status >= 200 && response.status < 300) || response.status === 304) {
        console.error(response.status)
      }
      return response.json()
    })
    .then((json) => {
      if (json.code === 1) {
        throw new Error(json.message, 'CharterPage.js')
      }
      console.info(json)
      this.setState({ loading: false })
      this.props.nextStep(5)
    })
    .catch((err) => {
      console.error(err)
      this.setState({ loading: false })
      new NoticeMessage().createNotice({
        type: 'error',
        title: '错误提示',
        message: (err && err.message) ? err.message : err })
    })
  }

  // 獲取配置環境
  getConfigEvn (name) {
    const url = `${__CM_URL__}kmxes/${name}/configEnv`
    fetch(url)
    .then((response) => {
      if (!(response.status >= 200 && response.status < 300) || response.status === 304) {
        console.error(response.status)
      }
      return response.json()
    })
    .then((json) => {
      console.info(json)
      if (json.code === 1) {
        throw new Error(json.message, 'CharterPage.js')
      }
      const hosttype = json.body.serviceMappings.filter(x => x.serviceName === 'kafka')[0]['hostType']
      // console.info(json.body.serviceMappings.filter(x => x.serviceName === 'kafka'))
      this.setState({
        body: json.body,
        activeNode: json.body.hosts[hosttype].length !== 0 ? [json.body.hosts[hosttype][0]['hostId']] : []
      })
    })
    .catch((err) => {
      console.error(err)
      new NoticeMessage().createNotice({
        type: 'error',
        title: '错误提示',
        message: (err && err.message) ? err.message : err })
    })
  }

  selectChange (val, name) {
    if (name === 'kafka') {
      this.setState({
        activeNode: val
      })
    }
  }

  getAllKmxNodes (name) {
    const url = `${__CM_URL__}kmxes/${name}/cm/allHosts`
    fetch(url)
    .then((response) => {
      if (!(response.status >= 200 && response.status < 300) || response.status === 304) {
        console.error(response.status)
      }
      return response.json()
    })
    .then((json) => {
      if (json.code === 1) {
        throw new Error(json.message, 'CharterPage.js')
      }
      this.setState({
        allNodes: json.body.items
      })
    })
    .catch((err) => {
      console.error(err)
      new NoticeMessage().createNotice({
        type: 'error',
        title: '错误提示',
        message: (err && err.message) ? err.message : err })
    })
  }

  setDiskNodes () {
    const { allNodes, activeNode } = this.state
    const diskArr = allNodes.filter((v) => {
      return activeNode.indexOf(v.hostId) > -1
    })
    const allDiskMess = allNodes.map((disk) => disk.disks).reduce((rel, v) => {
      return rel.concat(v)
    }, [])

    // a[0].filter((v) => a.slice(1).filter((vs) => vs.indexOf(v) >= 0).length  === a.length - 1);

    const diskObjects = diskArr.map((item) => {
      return item.disks.map(di => di.mountPoint)
    })
    const binji = (() => {
      if (diskObjects.length === 1) {
        return diskObjects[0]
      } else if (diskObjects.length > 1) {
        return diskObjects[0].filter((v) =>
        diskObjects.slice(1).filter((vs) => vs.indexOf(v) >= 0).length === diskObjects.length - 1)
      }
    })()
    const currentDisks = allDiskMess.filter((v) => {
      return binji && binji.indexOf(v.mountPoint) > -1
    }).filter((x) => binji && binji.indexOf(x.mountPoint) > -1)

    let currentDisksObj = {}
    currentDisks.forEach((item) => {
      if (currentDisksObj[item.mountPoint]) {
        currentDisksObj[item.mountPoint].push(item.capacity)
      } else {
        currentDisksObj[item.mountPoint] = []
        currentDisksObj[item.mountPoint].push(item.capacity)
      }
    })

    const lastDisks = (() => {
      let arr = []
      for (const key in currentDisksObj) {
        if (!key) return arr
        arr.push({ diskName: key, rels: Math.min.apply(Math, currentDisksObj[key]) })
      }
      return arr
    })()

    const formatBytes = (bytes, decimals) => {
      if (bytes === 0) return '0 Bytes'
      const k = 1000
      const dm = decimals || 2
      const size = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'EB', 'ZB', 'YB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))

      return `${parseFloat(bytes / Math.pow(k, i)).toFixed(dm)} ${size[i]}`
    }
    return lastDisks.map((op) => {
      return <Option key={op.diskName} value={op.diskName}>
        <Icon type='save' />
        {`${op.diskName}--${formatBytes(op.rels, 2)}`}
      </Option>
    })
  }

  checkConfirm (rule, value, callback) {
    const reg = /^[1-9]\d*$/
    if (value && !reg.test(value)) {
      callback(new Error('保证kafka数据副本为正整数！'))
    } else {
      callback()
    }
  }

  render () {
    const { getFieldDecorator } = this.props.form
    const { body, loading } = this.state
    const formItemLayout = {
      labelCol: { span: 8 },
      wrapperCol: { span: 24 }
    }
    return (
      <div className={styles['charter']}>
        <div className={styles['main']}>
          <div className={styles['box']}>
            <Form>
              {
                body.serviceMappings && body.serviceMappings.map((item) => {
                  return <div key={item.serviceName}>
                    <header>
                      <h4 style={{ color: '#fff' }}>{item.serviceName}</h4>
                    </header>
                    <article>
                      {
                        item.configurable
                          ? <ul>
                            <li>
                              <FormItem
                                >
                                {getFieldDecorator(item.serviceName, {
                                  rules: [{ required: true, message: '请保证填写' }],
                                  initialValue: R.filter(x => x.hostname, body.hosts[item.hostType])[0] &&
                                  R.filter(x => x.hostname, body.hosts[item.hostType])[0]['hostId']
                                })(
                                  <Select mode={item.many ? 'tags' : null}
                                    onChange={(val) => { this.selectChange(val, item.serviceName) }}>
                                    {
                                      !R.isEmpty(body.hosts[item.hostType])
                                        ? R.filter(x => x.hostname, body.hosts[item.hostType]).map((op, i) => {
                                          return <Option value={op.hostId} key={`${item.serviceName}${op.hostname}`}>
                                            {op.hostname}
                                          </Option>
                                        })
                                      : null
                                    }
                                  </Select>
                                )}
                              </FormItem>
                            </li>
                          </ul>
                        : <div className={styles['warn-text']}>不可配置</div>
                      }
                    </article>
                  </div>
                })
              }
              <FormItem {...formItemLayout} label='kafka数据磁盘'>
                {getFieldDecorator('kafka-disks', {
                  rules: [{ required: true, message: '请保证填写！' }]
                })(
                  <Select mode='tags'>
                    {
                      this.setDiskNodes()
                    }
                  </Select>
                )}
              </FormItem>
              <FormItem {...formItemLayout} label='kafka数据副本数'>
                {getFieldDecorator('kafka-replicationFactor', {
                  rules: [{ required: true, message: '请保证填写！' }, {
                    validator: this.checkConfirm
                  }],
                  initialValue: 1
                })(
                  <Input />
                )}
              </FormItem>
            </Form>
          </div>
        </div>
        <div className={styles['btn']}>
          <div style={{ float: 'right' }}>
            {
              // <Button onClick={() => { this.stepClick('pre') }}>上一步</Button> &emsp;
            }
            <Button onClick={() => { this.stepClick('next') }} type='primary' loading={loading}>下一步</Button>
          </div>
        </div>
      </div>
    )
  }
}

export default Form.create()(CharterPage)
